package gcmiddleware

import (
	"database/sql"
	"net/http"
	"strconv"
	"strings"

	"gitee.com/githubdog/goci"
	"gitee.com/githubdog/goci/tools/myjwt"
	"github.com/gin-gonic/gin"
)

type JwtCheckParam struct {
	Config         myjwt.JwtConf
	DebugUserIDStr string
	OtherJwtKey    []string // 除 head -> Authorization 之外的 url param
	CookieTokenKey string
	QueryFn        func(string) (interface{}, error)
	ErrorFn        func(*gin.Context, error)
}

func JwtCheck(p JwtCheckParam) gin.HandlerFunc {
	return func(c *gin.Context) {
		idStr := ""
		id, _ := strconv.Atoi(p.DebugUserIDStr)
		if id <= 0 {
			token := c.Request.Header.Get("Authorization")
			if token == "" {
				for _, v := range p.OtherJwtKey {
					if val := c.Query(v); val != "" {
						token = val
						break
					}
				}
			} else if strings.HasPrefix(token, "Bearer ") {
				token = strings.TrimSpace(token[7:])
			}
			if claims, e := myjwt.ParseToken(token, p.Config); e == nil {
				idStr = claims.Id
			}
		} else {
			idStr = p.DebugUserIDStr
		}
		if idStr != "" && p.QueryFn != nil {
			if user, err := p.QueryFn(idStr); err == nil {
				c.Set(goci.GinUserKey, user)
			} else if err != sql.ErrNoRows {
				if p.ErrorFn == nil {
					c.AbortWithStatus(http.StatusInternalServerError)
				} else {
					p.ErrorFn(c, err)
				}
			}
		}
	}
}
